import { initState } from "./initState.js";
import { compileToFunction } from "./compile/index.js";
import { mergeOptions } from "./utils/index"; //用来合并组件内的created updated生命周期函数等

import { mountComponent, callHook } from "./lifecycle.js";
export function initMixin(Vue) {
  //方法传参数Vue构造函数
  Vue.prototype._init = function (options) {
    console.log(
      "vue初始化操作 //或者//是自定义组件也调用_init()+配置项选择",
      this,
      "this",
      this.constructor.options,
      "this.constructor.options",
      options,
      "options",
    );
    const vm = this;
    // vm.$options = options; // 将用户选择挂载到实例上
    vm.$options = mergeOptions(this.constructor.options, options); //组件内的--对象（created,watch,等）合并到全局的定义的对象（created，watch,等）
    console.log(
      vm.$options,
      "组件内的对象和全局mixin对象合并以后的新的对象options，挂载到vm实例上",
    );
    //数据初始化之前
    callHook(vm, "beforeCreate");
    // 真正的初始化状态--props--data-watch-computed-methods
    initState(vm);
    //数据初始化之后
    callHook(vm, "created");

    // 模板编译
    if (vm.$options.el) {
      //调用方法$mount进行手动挂载 new Vue({}).$mount("#app") // new Vue({el: '#app'})
      vm.$mount(vm.$options.el);
    }
  };
  // 创建$mount方法
  Vue.prototype.$mount = function (el) {
    console.log(el, this, "el-el-el");
    //a: 根据vue2 生命周期图来理解其实现原理
    let vm = this;
    let options = vm.$options;
    el = document.querySelector(el); //获取el下的dom元素
    vm.$el = el; //将老的dom挂载到vue实例上，以便后续访问到
    //b:
    if (!options.render) {
      //没用render函数
      let template = options.template;
      if (!template && el) {
        // template不存在 但是el存在
        console.log(el, "el-outHTML"); //<div id="app">hello: {{name}}</div>
        template = el.outerHTML;
        //1. 得到render函数之后 将render函数变成vnode （2） vnode变成真实Dom 然后放到页面上去
      } else {
        template = options.template; // 没有el 一般是组件的挂载
      }
      // 编译模板 生成 render函数 ===> ast==》render字符串==》 通过new Function()变成render函数
      let render = compileToFunction(template);
      console.log(render, "render---字符串");
      options.render = render; //挂载到options上
    }
    //c:: console.log("$mount template-------------->", template);
    // 调用 render 实现页面渲染
    console.log(options.render, "render-----options");
    // 组件的挂载
    console.log(el, "之前老的el");
    mountComponent(vm, el); // 里面调用了_update和_render方法
  };
}
//<div id="app">hello: {{name}}</div>
//ast 语法树(div+ js + css等)   vnode:{} (虚拟dom)一个对象只能操作节点 (div)

// ast

/**
 * {
 *   tag: 'div',
 *   attrs: [
 *     {id: 'app'}
 *   ],
 * childrend: [
 *     {
 *       tag: '',
 *       text: 'heelo',
 *      }
 *  ]
 *
 * }
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 * * */
